#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define DATA_SIZE       100     // 内存元素的个数
#define RAND_NUM_RANGE  1000    // 随机数的获取范围

/**
  * @brief  交换两个数据
  * @note   默认整型数据(int、char等)
  * @param  num1：要交换数据1
  *         num2：要交换数据2
  * @retval None
  */
void BUBBLE_SORT_Swap(int *num1, int *num2)
{
    int tmp;        // 交换两个数据的中间值
    
    tmp   = *num1;  // 想一想装满可乐的瓶子想要倒进装满七喜的瓶子，应该怎么做？ 先拥有一个空瓶子 
    *num1 = *num2;
    *num2 = tmp;
}

/**
  * @brief  显示数据
  * @note   None
  * @param  data_p：指向要显示数据内存的指针
  *         len：   数据内存的长度
  * @retval None
  */
void BUBBLE_SORT_Show(int data_p[], int len)
{
    for (int i = 0; i < len; i++)
    {
        printf("%d\t", *(data_p+i));
    }
    printf("\n");
}


/**
  * @brief  获取随机数，并返回
  * @note   None
  * @param  size: rand函数随机数范围的最大值
  * @retval 返回获取得到的随机数
  */
int BUBBLE_SORT_Rand(int size)
{
    // 1、判断传进来的范围值，是否超出范围
    if(size > 32767)
        return -1;

    // 2、返回随机数
    return rand()%(size+1);
}


/**
  * @brief  冒泡排序
  * @note   None
  * @param  data_p：指向要排序的内存的指针
  *         len：   排序内存元素的个数
  * @retval None
  */
int BUBBLE_SORT_DataSort(int data_p[], int len)
{
    // (1)、判断传进来的指向需要排序的内存的指针，是否为NULL，为空退出
    if (len < 1)
    {
        return -1;
    }
    
    // (2)、相关变量
    int i    = 0;
    int j    = 0;    
    int k    = 0;

    int flag = 1;

    // (3)、排序
    while (1)
    {
        // 0、每次进行一次排序循环，让这个flag置为0
        flag = 1;

        // 1、一次排序的规律
        for (int i = 0; i < len-1-j; i++)
        {
            // 2、如果第i个数据小于等于第i+1个数据，重新循环比较下去
            if (data_p[i] <= data_p[i+1])
            {
                continue;
            }

            // 3、如果第i个数据大于第i+1个数据，那么交换两个数据
            BUBBLE_SORT_Swap(&data_p[i], &data_p[i+1]);  
            flag = 0;       // 此次排序需要交换数据的情况(意味着还需要再排)  
        }

        // 这个flag==1证明这个内存里面的数据，已经排无可排，直接退出这个循环
        if(flag == 1)  
            break;
 

        // 4、下一次循环，因为上一次循环，已经排好了一个最大的数据了，所以此处需要减1
        j++;        
    }

    // (4)、成功返回0
    return 0;
}



int main(int argc, char const *argv[])
{
    // 0、我们是伪随机，所以需要有一个随时变化的种子(时间)
    srand(time(NULL));              

    // 1、随机生成数据
    int data_buf[DATA_SIZE] = {0};
    for (int i = 0; i < DATA_SIZE; i++)
    {
        data_buf[i] =  BUBBLE_SORT_Rand(RAND_NUM_RANGE);
    }
    
    // 2、打印生成的随机数据(原数据)
    printf("原数据：\n");
    BUBBLE_SORT_Show(data_buf, DATA_SIZE);

    printf("排序后的数据：\n");
    BUBBLE_SORT_DataSort(data_buf, DATA_SIZE);
    BUBBLE_SORT_Show(data_buf, DATA_SIZE);
    
    return 0;
}
